﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections.Specialized;
using Vbyte.Configuration;

namespace Vbyte.DataSource.Utility
{
    public static class DataBindExtension
    {   
        
        /// <summary>
        /// 通过词典数据绑定实例
        /// </summary>
        /// <typeparam name="T">实例类型</typeparam>
        /// <param name="instance">当前实例</param>
        /// <param name="objDict">词典数据</param>
        /// <returns></returns>
        public static T DataBind<T>(this T instance, Dictionary<string, object> objDict)
        {
            if (instance == null) return default(T);
            Type t = instance.GetType();
            //路径映射配置词典
            Dictionary<string, string> keyMap = JSONPathAttribute.GetMappingDict(t);
            JSONParse jParse = new JSONParse(objDict);

            //数组子对象集合(为后续从父级对象继承属性关联)
            List<PropertyInfo> childPropList = new List<PropertyInfo>();

            foreach (string key in objDict.Keys)
            {
                PropertyInfo pi = t.GetProperty((keyMap.ContainsKey(key)) ? keyMap[key] : key);
                if (pi != null)
                {
                    try
                    {
                        #region 绑定对象的值
                        //数组对象
                        if (pi.PropertyType.IsArray)
                        {
                            object arrObject = typeof(JSONParse).GetMethod("GetObjectArray")
                                .MakeGenericMethod(pi.PropertyType.GetElementType())
                                .Invoke(jParse, new object[] { key });

                            if (arrObject != null) childPropList.Add(pi);
                            pi.SetValue(instance, arrObject, null);
                        }
                        else
                        {
                            if (objDict[key] == null)
                            {
                                pi.SetValue(instance, objDict[key], null);
                            }
                            else
                            {
                                #region 嵌套复合对象
                                if (objDict[key].GetType() == typeof(Dictionary<string, object>))
                                {
                                    object innerObj = typeof(JSONParse).GetMethod("GetObject")
                                        .MakeGenericMethod(pi.PropertyType)
                                        .Invoke(jParse, new object[] { key });

                                    pi.SetValue(instance, innerObj, null);
                                }
                                else
                                {
                                    if (pi.PropertyType != objDict[key].GetType())
                                    {
                                        //当数据内容不为空时
                                        if (!string.IsNullOrEmpty(objDict[key].ToString()))
                                        {
                                            pi.SetValue(instance, Convert.ChangeType(objDict[key], pi.PropertyType), null);
                                        }
                                    }
                                    else
                                    {
                                        pi.SetValue(instance, objDict[key], null);
                                    }
                                }
                                #endregion
                            }
                        }
                        #endregion
                    }
                    catch (Exception exp)
                    {
                        //Log("Error-JSON" + DateTime.Now.ToString("yyyy-MM-dd"), sw =>
                        //{
                        //    sw.WriteLine("Name:{0}, Type:{1}", pi.Name, pi.PropertyType.FullName);
                        //    sw.WriteLine("JSON:{0}", (objDict[key] is Dictionary<string, object>) ? objDict[key].ToJSON() : objDict[key].ToString());
                        //    sw.WriteLine(exp.Message);
                        //    sw.WriteLine(exp.StackTrace);
                        //    sw.WriteLine();
                        //});
                    }
                }
            }

            #region 检查并绑定从父级对象关联的值
            //for (int m = 0, n = childPropList.Count; m < n; m++)
            //{
            //    PropertyInfo arrPi = childPropList[m];
            //    if (OrmHelper.HasAttribute(arrPi, typeof(ChildTableAttribute), true))
            //    {
            //        ChildTableAttribute cAttr = OrmHelper.GetMemberInfoCustomAttributes<ChildTableAttribute>(arrPi, true)[0];
            //        cAttr.BindChildFromParent(instance, arrPi);
            //    }
            //}
            #endregion

            return instance;
        }

    }
}
